#include "stdafx.h"
//#include "list2d.h"
using namespace std;
list2d::list2d()
	{;}
list2d::list2d(string root,string name)
{
	unsigned int col;
	unsigned int row;
	string descript;
	double help;
	unsigned int count;

	file=root+name;
	ifstream in(file.c_str());
	if (!in) {
		cout<<"!!!FAIL!!! ..reading"<<file<<endl;
		std::cerr<<"!!!FAIL!!! ..reading"<<file<<endl;
		err::err2("Fail reading"+file);
	}
	// first values for width of array and nodata
	in>>nrows;
	in>>ncols;
	in>>nodata;
	count=0;
	do{
			in>>descript;
			var_id.push_back(descript);
			
			count++;	
	}
	while (count<ncols);
	for(row=0;row<nrows;row++){
		in>>descript;
		row_id.push_back(descript);
         //       cout<<endl<<row_id[row]<<endl;
		for(col=0;col<var_id.size();col++){
			in>>help;
			var[var_id[col]].push_back(help);
                     //   cout<<var_id[col]<<"\t"<<var[var_id[col]][row]<<"\t";
		}
                cout<<endl;
	}
}
list2d::~list2d(){	
}
list2d::list2d(vector<string> irow_id,vector<string> ivar_id,double inodata)
{
	unsigned int row,col;
	this->row_id=irow_id;
	this->var_id=ivar_id;
	this->nodata=inodata;
	this->ncols=this->row_id.size();
	this->nrows=this->var_id.size();
	vector <double> nullvect;
	for(col=0;col<var_id.size();col++)
	{
		var[var_id[col]]=nullvect;
		for(row=0;row<row_id.size();row++){
			var[var_id[col]].push_back(nodata);
		}
	}

}
int list2d::print(){
	unsigned int col,row;

	cout<<"This is list2d: "<<file<<endl;
	cout<<"Number of Variables: "<<ncols<<endl;
	cout<<"Number of cells: "<<nrows<<endl;
	cout<<"Coding for nodata: "<<nodata<<endl;
	for (col=0;col<ncols;col++){
		cout<<var_id[col]<<endl;
		for(row=0;row<nrows;row++){
			cout<<var[var_id[col]][row]<<"\t";
		}
		cout<<endl;
	}
	return 0;
}

int list2d::write()
{
	unsigned int row,col;
	ofstream out(file.c_str());
	if (!out) {
		cout<<"!!!FAIL!!! ..reading"<<file<<endl;
		std::cerr<<"!!!FAIL!!! ..reading"<<file<<endl;
		err::err2("Fail reading"+file);
	}
	out<<nrows<<endl<<ncols<<endl<<nodata<<endl;
	for(col=0;col<var_id.size();col++)
	{
		out<<var_id[col]<<"\t";
	}
	out<<endl;
	 for(row=0;row<nrows;row++)
	 {
		out<<row_id[row]<<"\t";
		for(col=0;col<ncols;col++)
		{
			out<<this->get_val(var_id[col],row)<<"\t";
		}
		out<<endl;
	 }
	 return 0;
	
}
int list2d::get_pos_of_first_entry (string row_idstring)
{
	unsigned int row;
	
	for(row=0;row<row_id.size();row++)
	{
		if(row_id[row]==row_idstring)return row;
	}
	return-999999;
}
int list2d::get_pos_of_last_entry(string row_idstring)
{
	unsigned int row;
	if (row_id.size()<1){
		err::err2("list2d::get_pos_of_last_entry: no value in list ");
	}
	row=row_id.size();
	do{
		row--;
		if(row_id[row]==row_idstring)return row;
	}
	while(row>0);
	
	return-999999;
}
int list2d::test_for_variable(string col_idstring)
	{
		// searches for an variable_identifier
		// returns 0 if one exists	and 
		// otherwise it declares this new variable; col_idstring and returns 1
		vector <double> nullvect;
		vector <string> vect_idstring;
		int indic;

		vect_idstring.push_back(col_idstring);
		indic=Basics_map::check_for_keys(var,vect_idstring);
		if(indic==1)
		{
			 var_id.push_back(col_idstring);
			 var[col_idstring]=nullvect;
			 var[col_idstring].assign(nrows,nodata);
			 ncols++;
			 return 1;
		}
		
		return 0;
	}

double list2d::get_val(const string idstring,unsigned int row)
{
   map< string,vector <double > >::const_iterator it;
   it=this->var.find(idstring);
   if(it==var.end())err::err2("list2d::get_val: strange col indice");
   if(row>nrows-1)err::err2("list2d::get_val: strange row indice");
   return var[idstring][row];
}

list2d& list2d::operator=(const list2d &source)
		  {
				this->nrows=source.nrows;
				this->ncols=source.ncols;
				this->nodata=source.nodata;
				this->row_id=source.row_id;
				this->var_id=source.var_id;
				this->var=source.var;
				this->file=source.file;
                return *this;
		  }
int list2d::pop_back()
{
	if(this->nrows<=0) {
		err::err3 ("list2d::pop_back:This_list_is_already_empty");
		return 1;
	}
	map < string,vector<double> >::const_iterator it;
	for(it=this->var.begin();it!=var.end();it++)
	{
		var[it->first].pop_back();
	}
	nrows--;
	row_id.pop_back();
	return 0;
}
vector <string> list2d::get_key()
{
	return var_id;
}